package Donnees;

import Metier.Objets.Produit;
import Metier.Objets.Stock;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

public class DaoStock {
    
    private Connection connection;
    private Statement statement;
    private PreparedStatement preparedStatement;
    
    /**
     * Ajoute un stock en base de données avec ses paramètres
     * @param stock objet Stock à ajouter
     * @return l'id du nouveau stock en base
     * @throws SQLException 
     */
    public int ajouter(Stock stock) throws SQLException{
        int key = -1;
        try{
            //Récupération de la connexion
            connection = ConnectionFactory.getConnection();
            
            boolean estViennoiserie;
            String query;
            
            //Déclaration de la requête en fonction du type de produit
            if(estViennoiserie = stock.getDatePeremption() == null){
                query = "INSERT INTO LOT_STOCK (PRODUIT_id, quantite)"
                    + " VALUES (?, ?)";
            }
            else{
                query = "INSERT INTO LOT_STOCK (PRODUIT_id, quantite, date_peremption)"
                    + " VALUES (?, ?, ?)";
            }
            
            //Préparation de la requête
            preparedStatement = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
            preparedStatement.setInt(1, stock.getIdProduit());
            preparedStatement.setInt(2, stock.getQuantite());
            if(!estViennoiserie){
                Calendar cal = new GregorianCalendar();
                cal.setTime(stock.getDatePeremption());
                preparedStatement.setDate(3, new Date(cal.getTimeInMillis()));
            }
            
            //Exécution de la requête
            key = preparedStatement.executeUpdate();
        }
        finally{
            DbUtil.close(preparedStatement);
            DbUtil.close(connection);
        }
        return key;
    }
    
    /**
     * Supprime tout le stock renseigné
     * @param stock stock concerné
     * @throws SQLException 
     */
    public void supprimer(Stock stock) throws SQLException{
        try {
            String query = "DELETE FROM LOT_STOCK where id = " + stock.getId();
            connection = ConnectionFactory.getConnection();
            statement = connection.createStatement();
            statement.execute(query);
        } finally {
            DbUtil.close(statement);
            DbUtil.close(connection);
        }
    }
    
    /**
     * Récupère un stock à partir d'un produit
     * @param p  produit concerné
     * @return s Stock associé au produit p
     * @throws SQLException
     */
    public List<Stock> chercherStockParProduit(Produit p) throws SQLException{
        String where = " WHERE PRODUIT_id = " + p.getId();
        return chercherStock(where);
    }
    
    /**
     * Récupère un stock à partir d'un produit
     * @param id id du produit concerné
     * @return s Stock associé au produit p
     * @throws SQLException
     */
    public List<Stock> chercherStockParIdProduit(int id) throws SQLException{
        String where = " WHERE PRODUIT_id = " + id;
        return chercherStock(where);
    }
    
    /**
     * Récupère un stock à partir d'un produit
     * @param id  id du stock concerné
     * @return s Stock associé à l'ID donné
     * @throws SQLException
     */
    public Stock chercherStockParId(int id) throws SQLException{
        String where = " WHERE id = " + id;
        return chercherStock(where).get(0);
    }
    
    /**
     * Méthode privée de recherche en fonction d'une clause définie par une fonction publique
     * @param whereClause la clause spécifique à la fonction appelante
     * @return la liste représentant le résultat de la requête
     * @throws SQLException 
     */
    private List<Stock> chercherStock(String whereClause) throws SQLException{
        List<Stock> liste = new ArrayList<>();
        try {
            ResultSet rs;
            Stock s;
            String query = "SELECT * FROM LOT_STOCK " + whereClause;
            connection = ConnectionFactory.getConnection();
            statement = connection.createStatement();
            rs = statement.executeQuery(query);
            while (rs.next()) {
                if(rs.getDate("date_peremption") == null){
                    s = new Stock(rs.getInt("id"),rs.getInt("PRODUIT_id"),rs.getInt("quantite"));
                }
                else{
                    Calendar cal = new GregorianCalendar();
                    cal.setTime(rs.getDate("date_peremption"));
                    s = new Stock(rs.getInt("id"),rs.getInt("PRODUIT_id"),rs.getInt("quantite"), (rs.getDate("date_peremption") != null ? cal.getTime() : null));
                }
                liste.add(s);
            }
        } finally {
            DbUtil.close(statement);
            DbUtil.close(connection);
        }
        return liste;
    }
    /**
     * Récupère tous les stocks
     * @return Tous les stocks
     * @throws SQLException
     */
    public List<Stock> chercherStock() throws SQLException {
        return chercherStock("");
    }
    
    /**
     * Modifie le stock renseigné en base de données.
     * @param stock stock à modifier
     * @throws SQLException 
     */
    public void modifier(Stock stock) throws SQLException{
        try{
            //Récupération de la connexion
            connection = ConnectionFactory.getConnection();
            
            //Déclaration de la requête
            String query = "UPDATE LOT_STOCK SET PRODUIT_id = ?, quantite = ? WHERE id = ?";
            
            //Préparation de la requête
            preparedStatement = connection.prepareStatement(query);
            preparedStatement.setInt(1, stock.getIdProduit());
            preparedStatement.setInt(2, stock.getQuantite());
            preparedStatement.setInt(3, stock.getId());
            
            //Exécution de la requête
            preparedStatement.executeUpdate();
        }
        finally{
            DbUtil.close(preparedStatement);
            DbUtil.close(connection);
        }
    }
}
